<?php
    namespace Server\network;

    use lactone\Core\data\SocketData;
    use lactone\Core\Models\TaskModel;
    use lactone\Core\network\ServerInstance;
    use lactone\Core\Models\SpiderModel;
    use lactone\Core\Spider\Spiders;


    class Server extends ServerInstance{

        function run(){

            \Lactone::info($this->logMessage("Run Server!",'Server'));

            if(!$this->ip || !$this->port){
                throw new \Exception("请设置监听ip和port的端口!");
            }

            $this->set([
                'worker_num' => 4,
                'daemonize' => false,
                'max_request' => 10000,
                'dispatch_mode' => 1,
                'task_worker_num' => 8
            ]);


            $this->Listening(true);
        }


        /**
         * 对数据进行处理
         * @param $server
         * @param $fd
         * @param $from_id
         * @param $data
         */
        public function onReceive($server,$fd,$from_id,$data){

            \Lactone::debug($this->logMessage($data,'ServerListen'));

            $datas = $this->getData($data);

            foreach($datas as $d){

                \Lactone::debug($this->logMessage($d,'ToTask'));

                $DataObject = new SocketData($d);

                switch($DataObject->type){
                    case \Lactone::SPIDERLIVEACTION:
                        $this->liveSpiderProcess($server,$fd,$from_id,$DataObject);
                        break;
                    default:
                        $server->task( $d );
                }


            }

        }

        /**
         * 执行任务
         */
        public function onTask($server,$task_id,$from_id, $data){

            $DataObject = new SocketData($data);
            switch($DataObject->type){
                case 'task':
                    $this->taskProcess($DataObject);
                    break;
                case 'taskresult':
                    $this->taskResult($DataObject);
                    break;
                default:

            }
        }

        /**
         * 任务执行完成
         */
        public function onFinish($serv,$task_id, $data){
            \Lactone::debug($this->logMessage("onFinish,task id:".$task_id));
        }

        /**
         * 对数据进行处理
         * @param $server
         * @param $fd
         * @param $from_id
         * @param $data
         */
        /*public function onReceive($server,$fd,$from_id,$data){

            \Lactone::debug($this->logMessage($data,'ServerListen'));

            if($datas = $this->getData($data)){

                \Lactone::debug($this->logMessage($datas,'ServerListen'));

                foreach($datas as $d){
                    $Data = new SocketData($d);

                    switch($Data->type){
                        case \Lactone::SPIDERLIVEACTION:
                            $this->liveSpiderProcess($server,$fd,$from_id,$Data);
                            break;
                        case 'task':
                            $this->taskProcess($Data);
                            break;
                        case 'taskresult':
                            $this->taskResult($Data);
                            break;
                        default:

                    }
                }
            }



        }*/

        /**
         * 在线蜘蛛处理
         * @param $server
         * @param $fd
         * @param $from_id
         * @param $data
         */
        protected function liveSpiderProcess($server,$fd,$from_id,$Data){
            $Connection = $server->connection_info($fd);
            $SpiderPort = $Data->data['port'];
            $SpiderIp   = $Connection['remote_ip'];

            if(!\Lactone::$Spiders->hasSpider($SpiderIp,$SpiderPort)){
                \Lactone::info($this->logMessage("当前蜘蛛[$SpiderIp,$SpiderPort]没有被注册",'LiveSpider'));

                if($Spider = SpiderModel::create(['ip'=>$SpiderIp,'port'=>$SpiderPort,'status'=>Spiders::Live_Status])){
                    \Lactone::$Spiders->addSpider($Spider);
                }else{
                    \Lactone::warning($this->logMessage("注册蜘蛛失败",'注册蜘蛛'));
                }
            }else{
                \Lactone::debug($this->logMessage("当前蜘蛛被注册",'LiveSpider'));

                \Lactone::$Spiders->liveSpider($SpiderIp,$SpiderPort);
            }
        }


        /**
         * 任务处理
         * @param $Data
         */
        protected function taskProcess($Data){
            \Lactone::debug($this->logMessage("task",'task'));

            if($task = json_decode($Data->data,true)){
                $task_hash = TaskModel::create_hash($task['url'],$task['request']);
                $p_id = isset($task['p_id'])?$task['p_id']:0;
                $level = isset($task['level'])?$task['level']:0;

                if(!TaskModel::hasTask($task_hash)){
                    $Spider = \Lactone::$Spiders->getFreeSpider();
                    if(!TaskModel::create(['p_id'=>$p_id,'level'=>$level,'hash'=>$task_hash,'s_id'=>$Spider->id,'url'=>$task['url'],'status'=>0,'request'=>serialize($task['request'])])){
                        \Lactone::warning($this->logMessage("任务添加失败",'task'));
                    }
                }else{
                    \Lactone::debug($this->logMessage("任务已经存在",'task'));
                }
            }
        }

        /**
         * 任务结果处理
         * @param $Data
         */
        protected function taskResult($Data){
            \Lactone::debug($this->logMessage("taskResult",'task'));

            if($task = json_decode($Data->data,true)){
                $task_id     = $task['task_id'];
                $task_result = $task['results'];

                $update = ['status'=>$task_result];
                if(TaskModel::table()->update($update,['id'=>$task_id])){
                    \Lactone::$Spiders->stepCutTaskFormTaskId($task_id);

                    \Lactone::debug($this->logMessage($task_id."任务更新成功"));
                }else{

                    \Lactone::warning($this->logMessage($task_id."任务更新失败"));
                }

            }
        }
    }